﻿#include "MiniMapWidget.h"
#include <GraphicsUtil.h>
#include <GraphicsScene.h>
#include <GraphicsView.h>
#include <QPainter>
#include <QMouseEvent>
#include <QTimer>

MiniMapWidget::MiniMapWidget(QWidget* parent)
	: QWidget(parent)
	, ui(new Ui::MiniMapWidgetClass())
{
	ui->setupUi(this);
	assert(parent);
	setMouseTracking(true);
	setCursor(Qt::SizeAllCursor);
	ui->graphicsView->installEventFilter(this);
	ui->graphicsView->setMouseTracking(true);
	m_maskWgt = new MiniMapMaskWidget(this);
	connect(m_maskWgt, &MiniMapMaskWidget::sigCenterMove, this, &MiniMapWidget::onCenterMove);
}

MiniMapWidget::~MiniMapWidget()
{
	delete ui;
}

void MiniMapWidget::setMinimapVisable(bool visable)
{
	m_isVisable = visable;
	onViewScaleChanged();
}

void MiniMapWidget::setScene(GraphicsScene* scene)
{
	m_scene = scene;
	ui->graphicsView->setScene(m_scene);
	m_maskWgt->setScene(scene);
}

void MiniMapWidget::paintEvent(QPaintEvent* event)
{
	QPainter painter(this);
	painter.setPen(Qt::NoPen);
	painter.setBrush(QColor(67, 67, 67));
	painter.drawRect(rect());
}

void MiniMapWidget::onCenterMove(const QPoint& center)
{
	const QPoint viewPos = ui->graphicsView->pos();
	const QPoint newCenter = center - viewPos;
	const QPointF viewCenter = ui->graphicsView->mapToScene(newCenter);
	m_scene->getView()->centerOn(viewCenter);
}

void MiniMapWidget::onViewScaleChanged()
{
	// 视图在场景中的位置
	GraphicsView* view = m_scene->getView();
	assert(view);
	QRectF viewSceneRect = view->mapToScene(view->rect()).boundingRect();
	GraphicsBaseItem* centerItem = m_scene->getCenterItem();
	if (!centerItem)
		return;
	const QRectF itemSceneRect = centerItem->getItemData().getScaleRect();

	const qreal factor = itemSceneRect.width() / itemSceneRect.height();
	QSize size = GraphicsUtil::getKeepRatioSize(m_perferredSize.width(), m_perferredSize.height(), factor, false).toSize();
	ui->graphicsView->setFixedSize(size);
	// 调整外边框距离为一个定值
	size += QSize(m_padding, m_padding);

	// 设置mask和minimap的尺寸
	m_maskWgt->setFixedSize(size);
	setFixedSize(size);

	// 设置父容器尺寸
	parentWidget()->setFixedSize(size + QSize(5 * 2, 5 * 2));

	// 目的是进入事件循环，使其在reszie后生效
	QTimer::singleShot(0, [=] {
		// 计算缩放,使其centerItem和ui->graphicsView同样大小
		const QSize viewSize = ui->graphicsView->size();
		qreal viewFactor = (qreal)viewSize.width() / ((qreal)itemSceneRect.width());
		QTransform viewTransform;
		viewTransform.scale(viewFactor, viewFactor);
		ui->graphicsView->setTransform(viewTransform);
		ui->graphicsView->centerOn(centerItem);

		// centerItem在scene中的坐标
		QPolygonF sourcePolygon;
		sourcePolygon << itemSceneRect.topLeft() << itemSceneRect.topRight()
			<< itemSceneRect.bottomRight() << itemSceneRect.bottomLeft();

		// centerItem在ui->graphicsView中的坐标
		const QPolygon itemViewPolygon = ui->graphicsView->mapFromScene(itemSceneRect);

		// 根据Item的4个坐标，求出变换矩阵，将视图的4个坐标进行映射
		QTransform transform;
		QTransform::quadToQuad(sourcePolygon, itemViewPolygon, transform);

		// 显示view进行坐标映射到ui->graphicsView
		QPolygonF viewPolygon;
		viewPolygon << viewSceneRect.topLeft() << viewSceneRect.topRight()
			<< viewSceneRect.bottomRight() << viewSceneRect.bottomLeft();
		QPolygonF targetPolygon = transform.map(viewPolygon);

		// 视图可见区域在minimap中的位置
		QRectF maskVisableRect = targetPolygon.boundingRect();
		// ui->graphicsView的坐标
		const QPoint viewPos = ui->graphicsView->pos();
		// 视图可见区域进行坐标偏移
		const QPointF newCenter = maskVisableRect.center() + viewPos;
		maskVisableRect.moveCenter(newCenter);
		m_maskWgt->setVisableRect(maskVisableRect.toRect());
		});

	// 检查是否需要显示
	const int viewWidth = view->width();
	const int viewHeight = view->height();
	const QRectF itemInViewRect = view->mapFromScene(itemSceneRect).boundingRect();
	if ((itemInViewRect.width() > viewWidth || itemInViewRect.height() > viewHeight)){
        if(m_isVisable){
            parentWidget()->show();
        }
        emit view->sigOutOfView(true);
	}
    else {
        parentWidget()->hide();
        emit view->sigOutOfView(false);
	}
}

